package com.ruoyi.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.blog.domain.BlogConfig;
import com.ruoyi.blog.domain.vo.ResultConfigVo;
import com.ruoyi.blog.mapper.BlogConfigMapper;
import com.ruoyi.blog.service.IBlogConfigService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.*;

@Service
public class BlogConfigServiceImpl implements IBlogConfigService {

    @Autowired(required = false)
    private BlogConfigMapper blogConfigMapper;


    @Override
    public List<BlogConfig> getBlogConfigList(QueryWrapper<BlogConfig> queryWrapper) {
        return blogConfigMapper.selectList(queryWrapper);
    }

    @Override
    public ResultConfigVo getBlogApiConfig() {
        return getStringObjectMap("is_api");
    }

    @Override
    public ResultConfigVo getBlogWebConfig() {
        return getStringObjectMap("is_web");
    }

    @Override
    public BlogConfig getBlogConfigByName(String name) {
        QueryWrapper<BlogConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("en_name", name);
        return blogConfigMapper.selectOne(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = IllegalAccessException.class)
    public Boolean updateBlogConfig(ResultConfigVo configVo) {
        // 使用反射进行将实体类反射为数据库列字段值
        List<Field> list = getPropertyList(configVo);
        for (Field field: list){
            try {
                field.setAccessible(true);
                // 设置更新值
                BlogConfig config = new BlogConfig();
                config.setValue(field.get(configVo));
                // 设置更新条件信息
                QueryWrapper<BlogConfig> wrapper = new QueryWrapper<>();
                wrapper.eq("en_name", StringUtils.toUnderScoreCase(field.getName()) );
                blogConfigMapper.update(config, wrapper);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }

    private ResultConfigVo getStringObjectMap(String is) {
        ResultConfigVo configVo = new ResultConfigVo();

        QueryWrapper<BlogConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(is,1);

        List<BlogConfig> list = getBlogConfigList(queryWrapper);
        list.forEach(item -> {
            if (isDate(item.getValue().toString() ) ){
                Date date = DateUtils.parseDate(item.getValue());
                setProperty(configVo, item.getEnName(), date);
            }else{
                setProperty(configVo, item.getEnName(), item.getValue() );
            }
        });
        return configVo;
    }


    private List<Field> getPropertyList(ResultConfigVo object) {
        List<Field> fieldList = new LinkedList<>();
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields){
            /** 过滤静态属性**/
            if(Modifier.isStatic(field.getModifiers())){
                continue;
            }
            /** 过滤transient 关键字修饰的属性**/
            if(Modifier.isTransient(field.getModifiers())){
                continue;
            }
            fieldList.add(field);
        }

        return fieldList;
    }

    /**
     * 反射设置属性
     * @param object
     * @param propertyName
     * @param value
     */
    private void setProperty(ResultConfigVo object, String propertyName, Object value) {

        String methodName = "set"+ StringUtils.convertToCamelCase(propertyName);
        try {
            Method methodFunc = object.getClass().getMethod(methodName, value.getClass());
            methodFunc.setAccessible(true);
            methodFunc.invoke(object, value);
        } catch (Exception e){
            e.printStackTrace();
        }

    }

    /**
     * 判断是否为日期
     * @param value
     * @return
     */
    private boolean isDate(String value) {
        try {
            DateFormat.getDateInstance().parse(value);
            return true;
        } catch (ParseException e) {
            return false;
        }
    }


}
